﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Administracja
{
    public partial class OsobyWplaty : Form
    {
        private readonly int _idO;

        private int _idF = 1;
        private readonly List<int> _idFl = new List<int>();
        private int _indexF = -1;

        private int _idW = 1;
        private readonly List<int> _idWl = new List<int>();
        private int _indexW;

        public OsobyWplaty(int idO)
        {
            InitializeComponent();
            _idO = idO;
            Wyswietl();
        }

        private void Wyswietl()
        {
            lista_faktur.Items.Clear();
            _idFl.Clear();

            OdswiezBilans();

            id_lab.Text = "ID: " + _idO;

            var reader2D = Baza.Wczytaj2D("SELECT Nazwisko, Imie, Notatka FROM OSOBY WHERE ID = '" + _idO + "' ORDER BY ID");
            imie_l.Text = reader2D[0][0];
            nazwisko_l.Text = reader2D[0][1];
            notatka.Text = reader2D[0][2];

            reader2D = Baza.Wczytaj2D("SELECT ID, Numer, Data, Suma_B, Oplata FROM FAKTURY WHERE ID_N = '" + _idO + "' ORDER BY NUMER, ID");
            foreach (List<string> reader1D in reader2D)
            {
                _idFl.Add(Int32.Parse(reader1D[0]));

                ListViewItem element = lista_faktur.Items.Add(reader1D[1]);
                element.SubItems.Add(reader1D[2].Substring(8, 2) + "." + reader1D[2].Substring(5, 2));

                double sumaB = Convert.ToDouble(reader1D[3].Replace(".", ","));
                element.SubItems.Add(string.Format("{0:N2}", sumaB));

                double oplata = Convert.ToDouble(reader1D[4].Replace(".", ","));
                element.SubItems.Add(string.Format("{0:N2}", sumaB - oplata));
            }

            double bilansD = Baza.LiczBilansOsob(_idO);
            if (bilansD < 0) bilans.ForeColor = System.Drawing.Color.Red;
            else bilans.ForeColor = System.Drawing.Color.Green;
            bilans.Text = "Bilans : " + string.Format("{0:N2}", bilansD) + " zł";

            try //po wyświetleniu przywraca starą pozycję zaznaczenia
            {
                if (lista_faktur.Items.Count != 0)
                {
                    lista_faktur.Items[_indexF].Selected = true;
                }
            }
            catch
            {
                lista_faktur.Items[lista_faktur.Items.Count - 1].Selected = true;
            }
        }

        private void WyswietlWplaty()
        {
            lista_wplat.Items.Clear();
            _idWl.Clear();

            var reader2D = Baza.Wczytaj2D("SELECT WPLATY.ID, WPLATY.DATA, KWOTA, NUMER, ODSETKI, SPOSOB, DOKUMENT, NUMER_DOK FROM WPLATY JOIN FAKTURY ON WPLATY.ID_F = FAKTURY.ID WHERE ID_F = '" + _idF + "' ORDER BY WPLATY.DATA");
            foreach (var reader1D in reader2D)
            {
                _idWl.Add(int.Parse(reader1D[0]));
                ListViewItem element = lista_wplat.Items.Add(reader1D[1].Substring(8, 2) + "." + reader1D[1].Substring(5, 2));
                element.SubItems.Add(string.Format("{0:N2}", Convert.ToDouble(reader1D[2].Replace(".", ","))));
                element.SubItems.Add(reader1D[3]);
                element.SubItems.Add(string.Format("{0:N2}", Convert.ToDouble(reader1D[4].Replace(".", ","))));
                element.SubItems.Add(reader1D[5]);
                element.SubItems.Add(reader1D[6]);
                element.SubItems.Add(reader1D[7]);
            }

            try
            {
                if (lista_wplat.Items.Count != 0)
                {
                    lista_wplat.Items[_indexW].Selected = true;
                }
            }
            catch
            {
                lista_wplat.Items[lista_wplat.Items.Count - 1].Selected = true;
            }
        }

        private void ObliczOdsetki(bool propozycja)
        {
            Baza.Ustaw("WPLATY");

            double wplata = Convert.ToDouble(wplata_box.Text.Replace(".", ","));   //kwota wpłaty
            var dataFaktury = DateTime.Parse(Baza.Wczytaj("SELECT Data FROM Faktury WHERE ID = '" + _idF + "'"));

            var rozliczenie = LiczOdsetki(dataFaktury, data_wplaty.Value, int.Parse(odsetkiProcNum.Value.ToString()), wplata);
            //Jesli propozycja to nie odejmuj kasy z tego co przyniosl najemca.
            //if (propozycja) rozliczenie[2] = rozliczenie[0] + rozliczenie[1];

            za_fv.Text = "Za FV: " + String.Format("{0:N2}", Math.Round(rozliczenie[0], 2));
            odsetki_l.Text = "Odsetki: " + String.Format("{0:N2}", Math.Round(rozliczenie[1], 2));
            razem_l.Text = "Razem: " + String.Format("{0:N2}", Math.Round(rozliczenie[0] + rozliczenie[1], 2));
            pozostalo_l.Text = "Pozostało: " + String.Format("{0:N2}", Math.Round(rozliczenie[2], 2));
            liczba_dni.Text = "Liczba dni: " + rozliczenie[3];

            if (!propozycja)
            {
                wplata_box.Text = Math.Round(rozliczenie[2], 2).ToString("0.00");
            }

            if (!propozycja)
            {
                string sposob = "G";
                string dokument = "FV";

                if (przelewRad.Checked)
                {
                    sposob = "P";
                    dokument = "W";
                }
                if (kp_rad.Checked) dokument = "KP";

                Baza.Zapisz("INSERT INTO WPLATY VALUES (GEN_ID(NUMERACJA_WPLATY,1),'" +
                    _idF + "','" +
                    data_wplaty.Value.Day + "." + data_wplaty.Value.Month + "." + data_wplaty.Value.Year + "','" +
                    rozliczenie[0].ToString().Replace(",", ".") + "','" +
                    rozliczenie[1].ToString().Replace(",", ".") + "','" +
                    sposob + "','" +
                    dokument + "','" +
                    numer_dok_box.Text + "');");

                Wyswietl();
                WyswietlWplaty();
            }
        }

        private void OdswiezBilans()
        {
            //Bilans odświeżamy tylko dla numeru != 0;
            if (Int32.Parse(Baza.Wczytaj("SELECT NUMER FROM FAKTURY WHERE ID='" + _idF + "'")) != 0)
            {
                //Aktualizacja Suma_B faktury
                var ceny = new List<double>();
                var vat = new List<int>();
                double sumaB = 0;

                var reader2D = Baza.Wczytaj2D("SELECT CENA, VAT FROM FAKTURY_SKLADNIKI JOIN SKLADNIKI ON FAKTURY_SKLADNIKI.ID_S"
                    + " = SKLADNIKI.ID WHERE ID_F = '" + _idF + "'");
                foreach (var a in reader2D)
                {
                    ceny.Add(Convert.ToDouble(a[0]));
                    vat.Add(Int32.Parse(a[1]));
                }

                for (int i = 0; i < ceny.Count; i++)
                {
                    sumaB += Math.Round(ceny[i] + ceny[i] * vat[i] / 100, 2);
                }

                Baza.Zapisz("UPDATE FAKTURY SET Suma_B = '" + sumaB.ToString().Replace(",", ".") + "' WHERE ID = '" + _idF + "';");

                //Aktualizacja oplaty danej fv
                var kwota = Convert.ToDouble(Baza.Wczytaj("SELECT SUM(Kwota) FROM WPLATY WHERE ID_F = '" + _idF + "'").Replace(".", ","));

                Baza.Zapisz("UPDATE FAKTURY SET Oplata = '" + kwota.ToString().Replace(",", ".") + "' WHERE ID = '" + _idF + "';");
            }
        }

        private void DodajWplate()
        {
            if (wplata_box.Text.CompareTo("0") != 0 && wplata_box.Text.Length != 0 && numer_dok_box.Text.Length != 0)
            {
                ObliczOdsetki(false);

                //Zerowanie parametrów tymczasowo wyłączone na prośbę mamy
                /*
                data_wplaty.Value = DateTime.Now;
                odsetkiCh.Checked = false;
                nadplataCh.Checked = false;
                gotowkaRad.Checked = true;
                fv_rad.Checked = true;
                numer_dok_box.Text = "";
                */
            }
            else
            {
                Wyjatki.Komunikat("Wypełnij wszystkie pola przed dodaniem wpłaty.", "Wypełnij pola", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Funkcja obliczająca odsetki od wplaty.
        /// </summary>
        /// <param name="dataOd">Data wystawienie FV.</param>
        /// <param name="dataDo">Data wplaty.</param>
        /// <param name="procent">Oprocentowanie odsetek w skali roku.</param>
        /// <param name="wplata">Kwota przyniesiona przez najemce.</param>
        /// <returns>Tablica 4 elementow: ZaFV, Odsetki, Pozostalo, liczbaDni</returns>
        private double[] LiczOdsetki(DateTime dataOd, DateTime dataDo, int procent, double wplata)
        {
            if (nadplataCh.Checked) //gdy nadplata
            {
                return new[] { wplata, 0.0, 0.0, 0.0 };
            }
            else
            {
                var reader1D = Baza.Wczytaj1D("SELECT Suma_B, Oplata FROM FAKTURY WHERE ID = '" + _idF + "'");
                var sumaB = Convert.ToDouble(reader1D[0].Replace(".", ","));
                var oplacono = Convert.ToDouble(reader1D[1].Replace(".", ","));

                double zaFv;

                if (oplacono < sumaB) //sprawdzenie, czy nie oplacono już więcej niż wynika to z faktur.
                {
                    zaFv = sumaB - oplacono;
                }
                else
                {
                    return new[] { 0.0, 0.0, wplata, 0.0 };
                }

                if (!odsetkiCh.Checked) //gdy bez nadplaty i bez odsetek
                {
                    return wplata >= zaFv ? new[] { zaFv, 0.0, wplata - zaFv, 0.0 } : new[] { wplata, 0.0, 0.0, 0.0 };
                }
                else //gdy odsetki
                {
                    if (dataOd.CompareTo(dataDo) >= 0)
                    {
                        throw new Exception("Błąd dat przy obliczaniu odsetek.");
                    }

                    int liczbaDni = (dataDo - dataOd).Days;
                    double odsetki = Math.Round(zaFv * Convert.ToDouble(procent) / 100 / 365 * liczbaDni, 2);

                    if (zaFv <= wplata - odsetki)
                    {
                        return new[] { zaFv, odsetki, wplata - zaFv - odsetki, Convert.ToDouble(liczbaDni) };
                    }
                    else
                    {
                        double tmpOproc = wplata / (zaFv + odsetki);

                        return new[] { zaFv * tmpOproc, odsetki * tmpOproc, 0.0, Convert.ToDouble(liczbaDni) };
                    }
                }
            }
        }

        #region handlery

        private void usun_fv_Click(object sender, EventArgs e)
        {
            string numer = Baza.Wczytaj("SELECT MAX(Numer) AS Numer FROM FAKTURY");

            if (numer == "0") Wyjatki.Komunikat("Nie ma faktur do usunięcia!", "Brak faktur", MessageBoxButtons.OK, MessageBoxIcon.Error);
            else
            {
                if (Wyjatki.Komunikat("Czy na pewno chcesz usunąć fakturę numer " + numer + " ?", "Usunąć?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    Baza.Zapisz("DELETE FROM FAKTURY_SKLADNIKI WHERE ID_F IN (SELECT ID FROM FAKTURY WHERE NUMER IN (SELECT MAX(Numer) FROM FAKTURY))",
                        "DELETE FROM WPLATY WHERE ID_F IN (SELECT ID FROM FAKTURY WHERE NUMER IN (SELECT MAX(Numer) FROM FAKTURY))",
                        "DELETE FROM FAKTURY WHERE ID IN (SELECT ID FROM FAKTURY WHERE NUMER IN (SELECT MAX(Numer) FROM FAKTURY))");
                }
            }
            Wyswietl();
        }

        private void dodaj_fv_Click(object sender, EventArgs e)
        {
            Baza.Ustaw("FAKTURY");

            var reader1D = Baza.Wczytaj1D("SELECT Data, ID_N, Termin_platnosci, Suma_b FROM FAKTURY WHERE ID IN (select Max(ID) FROM faktury WHERE ID_N = " + _idO + ");");
            var data = DateTime.Parse(reader1D[0]);
            string idN = reader1D[1];
            string termin = reader1D[2];
            string sumaB = reader1D[3];

            Baza.Zapisz("INSERT INTO FAKTURY VALUES(" +
                "GEN_ID(NUMERACJA_FAKTURY,1),GEN_ID(NUMER_FAKTURY,1),'" +
                data.Year + "." + data.AddMonths(1).Month + ".10','" +
                idN + "','" +
                "..........." + "','" +
                termin + "','" +
                sumaB.Replace(",", ".") + "','0');");

            var reader2D = Baza.Wczytaj2D("SELECT ID_S, Cena FROM Faktury_skladniki WHERE ID_F = '" + _idF + "'");
            foreach (var reader in reader2D)
            {
                Baza.Zapisz("INSERT INTO FAKTURY_SKLADNIKI VALUES(" +
                    "GEN_ID(NUMERACJA_FAKTURY_SKLADNIKI,1),GEN_ID(NUMERACJA_FAKTURY, 0),'" +
                    reader[0].Replace(",", ".") + "','" +
                    reader[1].Replace(",", ".") + "');");
            }

            _idF = Int32.Parse(Baza.Wczytaj("SELECT MAX(ID) FROM FAKTURY"));
            OdswiezBilans();

            lista_faktur_SelectedIndexChanged(this, EventArgs.Empty);
            Wyswietl();
            WyswietlWplaty();
        }

        private void edytuj_fv_Click(object sender, EventArgs e)
        {
            new OsobyFaktury(_idO, _idF).ShowDialog();

            Wyswietl();
        }

        private void usun_wp_Click(object sender, EventArgs e)
        {
            if (lista_wplat.Items.Count == 0)
            {
                Wyjatki.Komunikat("Brak wpłat do usunięcia.", "Brak wpłat", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                if (Wyjatki.Komunikat("Czy na pewno chcesz usunąć wpłatę na kwotę " + string.Format("{0:N2}", Convert.ToDouble(Baza.Wczytaj("SELECT Kwota FROM WPLATY WHERE ID = '" + _idW + "'")))
                    + " ?", "Usunąć?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    Baza.Zapisz("DELETE FROM WPLATY WHERE ID='" + _idW + "'");
                    Baza.Ustaw("WPLATY");
                }
            }

            Wyswietl();
            WyswietlWplaty();
        }

        private void edytuj_wp_Click(object sender, EventArgs e)
        {
            if (lista_wplat.Items.Count == 0)
            {
                Wyjatki.Komunikat("Brak wpłat do edycji.", "Brak wpłat", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                new OsobyWplatyEdycja(_idW).ShowDialog();
            }

            Wyswietl();
            WyswietlWplaty();
        }

        private void dodaj_wp_Click(object sender, EventArgs e)
        {
            DodajWplate();
        }

        private void lista_faktur_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                _indexF = lista_faktur.SelectedItems[0].Index;
            }
            catch
            {
                _indexF = lista_faktur.Items.Count - 1;
            }

            _idF = _idFl[_indexF];

            var numer = int.Parse(Baza.Wczytaj("SELECT Numer FROM FAKTURY WHERE ID = '" + _idF + "' ORDER BY NUMER, ID"));
            edytuj_fv.Enabled = numer != 0;

            WyswietlWplaty();
        }

        private void lista_wplat_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                _indexW = lista_wplat.SelectedItems[0].Index;
            }
            catch
            {
                _indexW = lista_wplat.Items.Count - 1;
            }

            _idW = _idWl[_indexW];
        }

        private void wplata_box_Click(object sender, EventArgs e)
        {
            wplata_box.SelectAll();
        }

        private void drukuj_konto_Click(object sender, EventArgs e)
        {
            //TODO:
            Wyjatki.Komunikat("I co klika? Jeszcze niezrobione!", "Brak funkcji", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void podglad_konta_Click(object sender, EventArgs e)
        {
            //TODO:
            Wyjatki.Komunikat("I co klika? Jeszcze niezrobione!", "Brak funkcji", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void gotowkaRad_CheckedChanged(object sender, EventArgs e)
        {
            fv_rad.Enabled = gotowkaRad.Checked;
            kp_rad.Enabled = gotowkaRad.Checked;
            fv_rad.Checked = gotowkaRad.Checked;
            wyciag_rad.Enabled = !gotowkaRad.Checked;
            wyciag_rad.Checked = !gotowkaRad.Checked;
        }

        private void zapisz_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void zaproponuj_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(wplata_box.Text) || wplata_box.Text != ("0"))
            {
                ObliczOdsetki(true);
            }
            else
            {
                Wyjatki.Komunikat("Wypełnij pole wpłaty przed proponowaniem rozliczenia.", "Wypełnij pola", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void nadplata_ch_CheckedChanged(object sender, EventArgs e)
        {
            if (nadplataCh.Checked) odsetkiCh.Checked = false;
        }

        private void odsetki_ch_CheckedChanged(object sender, EventArgs e)
        {
            if (odsetkiCh.Checked) nadplataCh.Checked = false;
        }

        private void CheckKeys(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                DodajWplate();
                e.KeyChar = (char)0;
            }
        }

        private void PrzepiszClick(object sender, EventArgs e)
        {
            var dataFaktury = DateTime.Parse(Baza.Wczytaj("SELECT Data FROM Faktury WHERE ID = '" + _idF + "'"));

            var rozliczenie = LiczOdsetki(dataFaktury, data_wplaty.Value, int.Parse(odsetkiProcNum.Value.ToString()), 1000000);

            wplata_box.Text = (rozliczenie[0] + rozliczenie[1]).ToString("0.00");
        }
        #endregion
    }
}
